package com.ruoyi.order.station.handle;

import com.github.s7connector.api.S7Connector;
import com.github.s7connector.api.factory.S7ConnectorFactory;
import com.github.s7connector.impl.serializer.S7SerializerImpl;
import com.ruoyi.order.domain.MesDetectNode;
import com.ruoyi.order.station.cmd.DB5409;
import com.ruoyi.order.station.request.*;
import com.ruoyi.order.station.response.DB5410Server;
import com.ruoyi.order.station.response.DB5439Server;
import com.ruoyi.order.station.response.PassResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
public class StationExchangeOneService {
    public final Map<String, S7Connector> connectorMap = new HashMap<>();
    /**
     * 获取当前节点 DB5409
     * @param node
     * @return
     */
    public DB5410PLC getDB5410(MesDetectNode node)
    {
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        try {
            return serializer.dispense(DB5410PLC.class, 5410, 0);
        }catch (Exception e) {
            log.error("读取DB5409异常,IP ={}", node.getIp());
            releaseConnection(node);
            e.printStackTrace();
            return null;
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 获取尾站 DB5419 工件下线信息
     * @param node
     * @return
     */
    public DB5419PLC getDB5419(MesDetectNode node)
    {
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        try{
            return serializer.dispense(DB5419PLC.class, 5419, 0);
        }catch (Exception e) {
            log.error("读取DB5419异常,IP ={}", node.getIp());
            releaseConnection(node);
            e.printStackTrace();
            return null;
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 获取尾站 DB5416
     * @param node
     * @return
     */
    public DB5416PLC getDB5416(MesDetectNode node)
    {
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        try {
            return serializer.dispense(DB5416PLC.class, 5416, 0);
        }catch (Exception e) {
            log.error("读取DB5416异常,IP ={}", node.getIp());
            releaseConnection(node);
            e.printStackTrace();
            return null;
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 写入尾站 DB5416
     * @param node
     * @return
     */
    public void writeDB5416(DB5416PLC db5416PLC, MesDetectNode node)
    {
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        try {
            serializer.store(db5416PLC, 5416, 150);
        }catch(Exception e){
            log.error("写入DB5416异常,IP ={}", node.getIp());
            releaseConnection(node);
            e.printStackTrace();
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 写入尾站 DB5419
     * @param node
     * @return
     */
    public void writeDB5419(DB5419PLC db5419PLC, MesDetectNode node)
    {
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        try {
            serializer.store(db5419PLC, 5419, 150);
        }catch(Exception e){
            log.error("写入DB5419异常,IP ={}" , node.getIp());
            releaseConnection(node);
            e.printStackTrace();
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 获取当前节点 DB5409
     * @param node
     * @return
     */
    public DB5409 getDB5409(MesDetectNode node)
    {
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        try {
            return serializer.dispense(DB5409.class, 5409, 0);
        }catch (Exception e) {
            log.error("获取DB5409异常,IP ={}", node.getIp());
            releaseConnection(node);
            e.printStackTrace();
            return null;
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 写入DB5409
     * @param db5409
     */
    public void writeDB5409(DB5409 db5409, MesDetectNode node){
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        try {
            serializer.store(db5409, 5409, 0);
        }
        catch(Exception e){
            log.error("写入DB5409异常,IP ={}" , node.getIp());
            releaseConnection(node);
            e.printStackTrace();
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 读取过站请求
     * @param node
     * @return
     */
    public PassRequest getPassRequest(MesDetectNode node)
    {
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        try {
            return serializer.dispense(PassRequest.class, 5411, 0);
        }catch (Exception e) {
            log.error("获取DB5411异常,IP ={}" , node.getIp());
            releaseConnection(node);
            e.printStackTrace();
            return null;
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    public void writePassResponse(PassResponse passResponse, MesDetectNode node){
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        try {
            serializer.store(passResponse, 5411, 150);
        }catch(Exception e){
            log.error("写入DB5411异常,IP ={}", node.getIp());
            releaseConnection(node);
            e.printStackTrace();
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * 写入DB5410Server
     * @param db5410Server
     */
    public void wirteDB5410Server(DB5410Server db5410Server, MesDetectNode node){
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        try {
            serializer.store(db5410Server, 5410, 150);
        }catch(Exception e){
            log.error("写入DB5410异常,IP ={}" , node.getIp());
            releaseConnection(node);
            e.printStackTrace();
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 接收完生产数据后写入DB5439Server
     * @param db5439Server
     */
    public void wirteProductDataResponse(DB5439Server db5439Server, MesDetectNode node, boolean isFirstStation){
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        int dbNum = 5439;
        if (isFirstStation){
            dbNum = 5449;
        }try {

            serializer.store(db5439Server, dbNum, 0);
        }catch(Exception e){
            log.error("写入DB{}}异常,IP ={}" ,dbNum ,node.getIp());
            releaseConnection(node);
            e.printStackTrace();
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 读取生产数据
     * @param node
     * @return
     */
    public Object readProductData(MesDetectNode node, boolean isFirstStation) {
        // 拼接完整类名
        String fullClassName = "com.ruoyi.order.station.request.instance." + node.getMachineCode() ;
        if (isFirstStation){
            fullClassName = fullClassName + "DataFirst";
        }else {
            fullClassName = fullClassName + "Data";
        }
        S7Connector connector = null;
        try {
            Class<?> clazz = Class.forName(fullClassName);

            connector = initConnection(node);
            S7SerializerImpl serializer = new S7SerializerImpl(connector);
            int dbNum = 5431;
            if (isFirstStation){
                dbNum = 5441;
            }
            return serializer.dispense(clazz, dbNum, 0);
        }  catch (ClassNotFoundException e) {
            releaseConnection(node);
            e.printStackTrace();
            return null;
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 读取生产数据,扩展字段
     * @param node
     * @return
     */
    public Object readProductDataExtended(MesDetectNode node) {
        // 拼接完整类名
        String fullClassName = "com.ruoyi.order.station.request.instance." + node.getMachineCode() + "Data_1";

        S7Connector connector = null;
        try {
            Class<?> clazz = Class.forName(fullClassName);

            connector = initConnection(node);
            S7SerializerImpl serializer = new S7SerializerImpl(connector);
            return serializer.dispense(clazz, 5432, 0);
        } catch (ClassNotFoundException e) {
            releaseConnection(node);
            e.printStackTrace();
            return null;
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 读取生产数据报文头
     * @param node
     * @param isFirstStation
     * @return
     */
    public ProcessRequest  readProductHeader(MesDetectNode node, boolean isFirstStation) {
        S7Connector connector = initConnection(node);
        S7SerializerImpl serializer = new S7SerializerImpl(connector);
        int dbNum = 5430;
        if (isFirstStation){
            dbNum = 5440;
        }
        try {
            return serializer.dispense(ProcessRequest.class, dbNum, 0);
        }catch (Exception e) {
            releaseConnection(node);
            e.printStackTrace();
            return null;
        }finally {
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    /**
     * 初始化连接
     * @return
     */
    public S7Connector initConnection(MesDetectNode  node) {

        S7Connector connector = null;
  /*      if (!connectorMap.containsKey(node.getNodeCode())){
            log.info("初始化连接：节点编码：{},IP:{}", node.getNodeCode(), node.getIp());
            connector = S7ConnectorFactory.buildTCPConnector()
                    .withHost(node.getIp())
                    .withRack(0)
                    .withSlot(1)
                    .build();

        }else {
            connector = connectorMap.get(node.getNodeCode());
        }*/

        log.info("初始化连接：节点编码：{},IP:{}", node.getNodeCode(), node.getIp());
        connector = S7ConnectorFactory.buildTCPConnector()
                .withHost(node.getIp())
                .withRack(0)
                .withSlot(1)
                .build();
        return connector;
    }

    /**
     * 释放连接
     * @param node
     */
    public void releaseConnection(MesDetectNode node){
        if (connectorMap.containsKey(node.getNodeCode())){
            S7Connector connector = connectorMap.get(node.getNodeCode());
            try {
                connector.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            connectorMap.remove(node.getNodeCode());
        }
    }
}
